package com.duan.laugh.upms.service.impl;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.duan.laugh.common.core.constants.CoreConstants;
import com.duan.laugh.common.core.exception.CheckedException;
import com.duan.laugh.common.core.exception.MultiplePassException;
import com.duan.laugh.common.core.exception.NotFoundPassException;
import com.duan.laugh.upms.api.pojo.dto.UserDetailDTO;
import com.duan.laugh.upms.api.pojo.entity.Pass;
import com.duan.laugh.upms.api.pojo.entity.Permission;
import com.duan.laugh.upms.api.pojo.entity.Role;
import com.duan.laugh.upms.api.pojo.entity.User;
import com.duan.laugh.upms.api.pojo.vo.UserParamsVO;
import com.duan.laugh.upms.mapper.UserMapper;
import com.duan.laugh.upms.service.PassService;
import com.duan.laugh.upms.service.PermissionService;
import com.duan.laugh.upms.service.RoleService;
import com.duan.laugh.upms.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 用户service实现
 *
 * @author duanjw
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private PassService passService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private UserMapper UserMapper;

    /**
     * 根据用户名获取用户
     *
     * @param username 用户名
     * @return
     */
    @Override
    public User getUserByUsername(String username) {
        return baseMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
    }

    /**
     * 根据用户信息，获取用户详细信息
     *
     * @param userParamsVO 用户参数
     * @return
     */
    @Override
    public UserDetailDTO getUserDetailByUserParams(UserParamsVO userParamsVO) {
        // 用户名
        String username = userParamsVO.getUsername();
        // 通行证
        Pass pass = null;
        Long passId = null;
        // 客户端id
        String clientId = userParamsVO.getClientId();
        final User user = getUserByUsername(username);
        // 用户不存在，登录失败
        if (null == user) {
            return null;
        }
        Long userId = user.getId();
        userParamsVO.setUserId(userId);
        final List<Pass> passList = passService.selectByUserParams(userParamsVO);
        // 没有通行证信息
        if (passList.isEmpty()) {
            throw new NotFoundPassException();
        }
        // 只有一个通行证，使用该通行证登录
        else if (passList.size() == CoreConstants.ONE) {
            pass = passList.get(CoreConstants.ZERO);
            passId = pass.getId();
            log.info("当前用户在系统【{}】有一个通行证【{}】，使用该通行证登录", clientId, pass.getName());
        }
        // 多个通行证，登录失败
        else if (passList.size() > CoreConstants.ONE) {
            log.error("当前用户在系统【{}】有【{}】个通行证，请选择通行证后登录", clientId, passList.size());
            throw new MultiplePassException();
        }

        UserDetailDTO userDetailDTO = new UserDetailDTO();
        userDetailDTO.setUser(user);
        userDetailDTO.setTenantId(pass.getTenantId());
        userDetailDTO.setTenantId(pass.getCreateTenantId());
        // 设置角色列表  （ID）
        List<String> roleIds = roleService.selectRoleByPassId(passId)
                .stream()
                .map(Role::getCode)
                .collect(Collectors.toList());
        userDetailDTO.setRoles(ArrayUtil.toArray(roleIds, String.class));

        // 如果没有角色，不加载权限，直接返回
        if (roleIds.isEmpty()) {
            log.info("当前用户在系统【{}】、租户【{}】没有角色信息，不加载权限登录", clientId, pass.getTenantId());
            return userDetailDTO;
        }

        // 设置权限列表（permission.code）
        Set<String> permissions = new HashSet<>();
        String roleIdsStr = StrUtil.join(",", roleIds);
        List<String> permissionList = permissionService.selectPermissionListByRoleIds(roleIdsStr)
                .stream()
                .filter(permission -> StringUtils.isNotEmpty(permission.getCode()))
                .map(Permission::getCode)
                .collect(Collectors.toList());
        permissions.addAll(permissionList);
        userDetailDTO.setPermissions(ArrayUtil.toArray(permissions, String.class));
        // 设置租户id
        return userDetailDTO;
    }

    /**
     * 通知接收对象类型为用户 - 查询用户基本信息
     *
     * @param receive
     * @return
     */
    public List<User> selectUsersByReceiveValue(String receive) {
        List<String> stringList = StrUtil.split(receive, ',', -1);
        return UserMapper.selectUsersByReceiveValue(stringList);
    }
}
